<template>
  <div class="base-map" ref="baseMapRef">
    <div v-if="!dataLoaded" class="loading">加载地图数据中...</div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import * as THREE from "three";
import * as d3 from "d3-geo";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";

// 引入地图组件类（而不是Vue组件）
import { BaseMapLayer } from "./maps/BaseMapLayer.js";
import { MidMapLayer } from "./maps/MidMapLayer.js";
import { TopMapLayer } from "./maps/TopMapLayer.js";

const baseMapRef = ref(null);
const jsondata = ref(null);
const dataLoaded = ref(false);

// THREE.js相关变量
let scene, camera, renderer, controls;
let animationFrameId;
let mapLayers = [];

const props = defineProps({
  // 加载地图的json文件
  geoJsonName: {
    type: String,
    default: "/src/components/baseMap/json/32000_full.json",
  },
});

// 墨卡托投影 - 所有层共享同一投影
const projection = d3
  .geoMercator()
  .center([118.767413, 32.041544])
  .translate([0, 0]);

// 创建纹理加载器 - 共享的纹理加载器
const textureLoader = new THREE.TextureLoader();
const rgbeLoader = new RGBELoader();
// 预加载纹理
// const matcapTexture = textureLoader.load(
//   "./model_assets/C7C7D7_4C4E5A_818393_6C6C74-512px.png"
// );

// ==================== 加载数据 ==================== //
const loadMapData = (geoJsonName) => {
  const loader = new THREE.FileLoader();
  loader.load(
    geoJsonName,
    (data) => {
      try {
        jsondata.value = JSON.parse(data);
        dataLoaded.value = true;
        initThree(); // 数据加载完成后初始化THREE.js
      } catch (error) {
        console.error("解析JSON数据失败:", error);
      }
    },
    (progress) => {
      console.log(
        "加载进度:",
        ((progress.loaded / progress.total) * 100).toFixed(2) + "%"
      );
    },
    (error) => {
      console.error("加载地图数据失败:", error);
    }
  );
};

// =================== 初始化THREE.js =================== //
const initThree = () => {
  console.log("初始化地图，使用数据:", jsondata.value);

  // 创建场景
  scene = new THREE.Scene();

  // 创建光源
  // ambientLight
  const ambientLight = new THREE.AmbientLight(0xffffff, 2);
  scene.add(ambientLight);

  // pointLight
  // const pointLight = new THREE.PointLight(0xffffff, 10000);
  // pointLight.position.set(80, 80, 80);
  // scene.add(pointLight);

  // 获取容器尺寸
  const container = baseMapRef.value;
  const width = container.clientWidth || window.innerWidth;
  const height = container.clientHeight || window.innerHeight;

  // 创建相机
  camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 1000);
  camera.position.set(0, 0, 30);
  camera.lookAt(0, 0, 0);

  // 创建渲染器
  renderer = new THREE.WebGLRenderer({
    alpha: true,
    antialias: true,
    powerPreference: "high-performance",
  });
  renderer.setSize(width, height);
  container.appendChild(renderer.domElement);

  // 创建控制器
  controls = new OrbitControls(camera, renderer.domElement);
  controls.enableDamping = true;

  // 初始化地图层
  initMapLayers();

  // 窗口大小变化监听
  window.addEventListener("resize", onWindowResize);

  // 启动渲染循环
  animate();
};

// =================== 初始化地图层 =================== //
const initMapLayers = () => {
  if (!jsondata.value) return;

  // 创建基础层
  const baseLayer = new BaseMapLayer(scene, projection, textureLoader);
  baseLayer.createFromGeoJson(jsondata.value);
  mapLayers.push(baseLayer);

  // 创建中间层
  const midLayer = new MidMapLayer(scene, projection, rgbeLoader);
  midLayer.createFromGeoJson(jsondata.value);
  mapLayers.push(midLayer);

  // 创建顶层
  const data = [
    {
      name: "南京市",
      value: 18841.8,
    },
    {
      name: "无锡市",
      value: 12270.2,
    },
    {
      name: "徐州市",
      value: 4385.2,
    },
    {
      name: "常州市",
      value: 4100.5,
    },
    {
      name: "苏州市",
      value: 3687.3,
    },
    {
      name: "南通市",
      value: 3500.1,
    },
    {
      name: "连云港市",
      value: 3400.2,
    },
    {
      name: "淮安市",
      value: 3300.4,
    },
    {
      name: "盐城市",
      value: 3200.3,
    },
    {
      name: "扬州市",
      value: 3100.6,
    },
    {
      name: "镇江市",
      value: 3000.2,
    },
    {
      name: "泰州市",
      value: 900.7,
    },
    {
      name: "宿迁市",
      value: 800.1,
    },
  ];
  const topLayer = new TopMapLayer(scene, projection, textureLoader, data);
  topLayer.createFromGeoJson(jsondata.value);
  mapLayers.push(topLayer);

  // 地图居中
  centerMap();
};

/**
 * 居中地图模型
 */
const centerMap = () => {
  if (!scene || !camera || !controls) return;

  // 创建一个虚拟对象来包含所有地图对象，用于计算边界
  const mapContainer = new THREE.Object3D();
  mapLayers.forEach((layer) => {
    if (layer.mapObject) {
      mapContainer.add(layer.mapObject.clone());
    }
  });
  scene.add(mapContainer);

  // 创建边界盒子并计算模型范围
  const box = new THREE.Box3().setFromObject(mapContainer);
  const size = box.getSize(new THREE.Vector3());
  const center = box.getCenter(new THREE.Vector3());

  // 计算合适的相机距离
  const maxDim = Math.max(size.x, size.y, size.z);
  const fov = camera.fov * (Math.PI / 180);
  let cameraDistance = maxDim / (2 * Math.tan(fov / 2));

  // 添加额外的距离
  cameraDistance *= 1.2;

  // 更新相机位置
  const direction = new THREE.Vector3(0, 0, 1).normalize();
  const cameraPosition = direction.multiplyScalar(cameraDistance).add(center);
  camera.position.copy(cameraPosition);
  camera.lookAt(center);

  // 更新控制器
  controls.target.copy(center);
  controls.update();

  // 从场景中移除临时容器
  scene.remove(mapContainer);

  console.log("地图已居中，中心点:", center, "尺寸:", size);
};

// =================== 渲染循环 =================== //
const animate = () => {
  animationFrameId = requestAnimationFrame(animate);

  // 更新控制器
  controls.update();

  // 渲染场景
  if (renderer && scene && camera) {
    renderer.render(scene, camera);
  }
};

// =================== 窗口大小变化时，更新相机和渲染器 =================== //
const onWindowResize = () => {
  if (!baseMapRef.value) return;

  const container = baseMapRef.value;
  const width = container.clientWidth || window.innerWidth;
  const height = container.clientHeight || window.innerHeight;

  if (!camera || !renderer) return;

  camera.aspect = width / height;
  camera.updateProjectionMatrix();

  renderer.setSize(width, height);

  // 窗口大小变化时重新居中模型
  centerMap();
};

// =================== 挂载组件时，加载地图数据 =================== //
onMounted(() => {
  // 加载地图数据
  loadMapData(props.geoJsonName);
});

// =================== 卸载组件时，释放资源 =================== //
onUnmounted(() => {
  cancelAnimationFrame(animationFrameId);
  if (renderer) {
    renderer.dispose();
  }

  // 清理层资源
  mapLayers.forEach((layer) => {
    if (typeof layer.dispose === "function") {
      layer.dispose();
    }
  });

  window.removeEventListener("resize", onWindowResize);
});
</script>

<style lang="scss" scoped>
.base-map {
  width: 100%;
  height: 100%;

  .loading {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    font-size: 18px;
    color: #666;
  }
}
</style>
